package com.jrx.anytxn.reporting.service.impl;

import com.jrx.anytxn.common.exception.TxnException;
import com.jrx.anytxn.common.uitl.DateUtils;
import com.jrx.anytxn.common.uitl.StringUtils;
import com.jrx.anytxn.customer.entity.CmLimitAdjustLog;
import com.jrx.anytxn.param.dto.limit.CreditLimitTypeRes;
import com.jrx.anytxn.param.entity.PrCreditLimitTemplate;
import com.jrx.anytxn.param.entity.PrOrganizationTable;
import com.jrx.anytxn.param.mapper.ext.ExtPrCreditLimitTemplateMapper;
import com.jrx.anytxn.param.service.limit.ICreditLimitTypeService;
import com.jrx.anytxn.param.service.system.IOrganizationTableService;
import com.jrx.anytxn.reporting.constant.ReportingConstant;
import com.jrx.anytxn.reporting.entity.MrCustomerInfo;
import com.jrx.anytxn.reporting.entity.MrLoanAccountInfo;
import com.jrx.anytxn.reporting.entity.MrPaymentLog;
import com.jrx.anytxn.reporting.entity.MrRepaymentPlan;
import com.jrx.anytxn.reporting.service.IReportingFileService;
import com.jrx.anytxn.transaction.entity.TlLoanStagingMapping;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.*;
import java.math.BigDecimal;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Service
public class ReportingFileServiceImpl implements IReportingFileService {

    private static final Logger logger = LoggerFactory.getLogger(ReportingFileServiceImpl.class);
    @Autowired
    private IOrganizationTableService organizationTableService;
    @Autowired
    private ICreditLimitTypeService creditLimitTypeService;
    @Resource
    private ExtPrCreditLimitTemplateMapper extPrCreditLimitTemplateMapper;

    @Override
    public void mergeFile(PrOrganizationTable org, String filePath, String fileName) throws IOException{
        logger.info("开始合并分库文件");
        Date bussinessDate = org.getToday();
        String toDay = DateUtils.format(bussinessDate,"yyyyMMdd");
        String reportingPath = filePath + org.getTenantId() + File.separator + toDay + File.separator;

        //生成客户文件
        mergeReportingFile(reportingPath,toDay,ReportingConstant.REPORTING_FILE_TYPE_CUSTOMER);

        //生成订单文件
        mergeReportingFile(reportingPath,toDay,ReportingConstant.REPORTING_FILE_TYPE_LOAN);

        //生成还款计划
        mergeReportingFile(reportingPath,toDay,ReportingConstant.REPORTING_FILE_TYPE_PAYMENT_PLAN);

        //生成还款流水
        mergeReportingFile(reportingPath,toDay,ReportingConstant.REPORTING_FILE_TYPE_PAYMENT);

        //生成调额文件
        mergeReportingFile(reportingPath,toDay,ReportingConstant.REPORTING_FILE_TYPE_LIMIT);

        //生成账单分期文件
        mergeReportingFile(reportingPath,toDay,ReportingConstant.REPORTING_FILE_TYPE_STAGING);

        File okFile = new File(reportingPath + toDay + ".ok");
        if(!okFile.exists()) {
            okFile.createNewFile();//按照租户生成OK文件
        }
    }

    @Override
    public String createCustomerFileMessage(MrCustomerInfo info) {

        StringBuffer sb = new StringBuffer();
        sb.append((info.getChannel()==null?"":info.getChannel()) + ReportingConstant.separator);
        sb.append((info.getCustomerId()==null?"":info.getCustomerId()) + ReportingConstant.separator);
        sb.append((info.getEcifId()==null?"":info.getEcifId()) + ReportingConstant.separator);
        sb.append(StringUtils.filterSpecialChar(info.getChineseName()) + ReportingConstant.separator);
        sb.append((info.getIdType()==null?"":info.getIdType()) + ReportingConstant.separator);
        sb.append((info.getIdNumber()==null?"":info.getIdNumber()) + ReportingConstant.separator);
        sb.append((info.getSex()==null?"":info.getSex()) + ReportingConstant.separator);
        String birthDate = info.getBirthDate() == null ? "": DateUtils.formatDate(info.getBirthDate());
        sb.append(birthDate  + ReportingConstant.separator);
        sb.append((info.getMarriage()==null?"":info.getMarriage() ) + ReportingConstant.separator);
        sb.append((info.getEducation()==null?"":info.getEducation() ) + ReportingConstant.separator);
        sb.append((info.getDegree()==null?"":info.getDegree() ) + ReportingConstant.separator);
        sb.append((info.getHomePhone()==null?"":info.getHomePhone() ) + ReportingConstant.separator);
        sb.append((info.getMobile()==null?"":info.getMobile() ) + ReportingConstant.separator);
        sb.append((info.getCompanyPhone()==null?"":info.getCompanyPhone() ) + ReportingConstant.separator);
        sb.append((info.getEmail()==null?"":info.getEmail() ) + ReportingConstant.separator);
        sb.append(StringUtils.filterSpecialChar(info.getAddress()) + ReportingConstant.separator);
        sb.append((info.getZipcode()==null?"":info.getZipcode() ) + ReportingConstant.separator);
        sb.append(StringUtils.filterSpecialChar(info.getHouseholdAddress()) + ReportingConstant.separator);
        sb.append(StringUtils.filterSpecialChar(info.getSpouseName()) + ReportingConstant.separator);
        sb.append((info.getSpouseIdType()==null?"":info.getSpouseIdType() ) + ReportingConstant.separator);
        sb.append((info.getSpouseIdNumber()==null?"":info.getSpouseIdNumber() ) + ReportingConstant.separator);
        sb.append(StringUtils.filterSpecialChar(info.getSpouseCompanyName()) + ReportingConstant.separator);
        sb.append((info.getSpouseHomePhone()==null?"":info.getSpouseHomePhone() ) + ReportingConstant.separator);
        sb.append((info.getSpouseOccuption()==null?"":info.getSpouseOccuption() ) + ReportingConstant.separator);
        sb.append(StringUtils.filterSpecialChar(info.getCompanyName()) + ReportingConstant.separator);
        sb.append((info.getIndustry()==null?"":info.getIndustry() ) + ReportingConstant.separator);
        sb.append(StringUtils.filterSpecialChar(info.getCompanyAddress()) + ReportingConstant.separator);
        sb.append((info.getCompanyZipcode()==null?"":info.getCompanyZipcode() ) + ReportingConstant.separator);
        sb.append((info.getBeginYear()==null?"":info.getBeginYear() ) + ReportingConstant.separator);
        sb.append((info.getJob()==null?"":info.getJob() ) + ReportingConstant.separator);
        sb.append((info.getTitle()==null?"":info.getTitle() ) + ReportingConstant.separator);
        sb.append((info.getAnnualIncome()==null?"0.00":info.getAnnualIncome().setScale(2, BigDecimal.ROUND_HALF_UP)) + ReportingConstant.separator);
        sb.append((info.getPayAccount()==null?"":info.getPayAccount()) + ReportingConstant.separator);
        sb.append((info.getPayBank()==null?"":info.getPayBank()) + ReportingConstant.separator);
        sb.append(StringUtils.filterSpecialChar(info.getResideAddress()) + ReportingConstant.separator);
        sb.append((info.getResideZipcode()==null?"":info.getResideZipcode()) + ReportingConstant.separator);
        sb.append((info.getResideCondition()==null?"":info.getResideCondition()) + ReportingConstant.separator);
        sb.append((info.getCustType()==null?"":info.getCustType()) + ReportingConstant.separator);
        String createTime = DateUtils.format(info.getCreateTime(),"yyyy-MM-dd HH:mm:ss");
        String updateTime = DateUtils.format(info.getUpdateTime(),"yyyy-MM-dd HH:mm:ss");
        sb.append(createTime + ReportingConstant.separator);
        sb.append(updateTime);

        return sb.toString();
    }

    @Override
    public String createLoanFileMessage(MrLoanAccountInfo info) {

        StringBuffer sb = new StringBuffer();
        sb.append((info.getLoanId()==null?"":info.getLoanId()) + ReportingConstant.separator);
        sb.append((info.getCustomerId()==null?"":info.getCustomerId()) + ReportingConstant.separator);
        sb.append((info.getOrganizationId()==null?"":info.getOrganizationId()) + ReportingConstant.separator);
        sb.append((info.getChannel()==null?"":info.getChannel()) + ReportingConstant.separator);
        sb.append((info.getProductId()==null?"":info.getProductId()) + ReportingConstant.separator);
        sb.append((info.getContractId()==null?"":info.getContractId()) + ReportingConstant.separator);
        sb.append((info.getContractNumber()==null?"":info.getContractNumber())  + ReportingConstant.separator);
        sb.append((info.getBusinessType()==null?"":info.getBusinessType()) + ReportingConstant.separator);
        sb.append((info.getLoanType()==null?"":info.getLoanType()) + ReportingConstant.separator);
        sb.append((info.getOccurPlace()==null?"":info.getOccurPlace())  + ReportingConstant.separator);
        sb.append((info.getLoanDurationUnit()==null?"":info.getLoanDurationUnit()) + ReportingConstant.separator);
        sb.append((info.getShareContractAmount()==null?"":info.getShareContractAmount())  + ReportingConstant.separator);
        sb.append((info.getTotalTenor()==null?"0":info.getTotalTenor()) + ReportingConstant.separator);
        sb.append((info.getPayedTenor()==null?"0":info.getPayedTenor()) + ReportingConstant.separator);
        String applyDate = info.getApplyDate() == null ? "": DateUtils.formatDate(info.getApplyDate());
        sb.append(applyDate + ReportingConstant.separator);
        String releaseDate = info.getReleaseDate() == null ? "": DateUtils.formatDate(info.getReleaseDate());
        sb.append(releaseDate + ReportingConstant.separator);
        String overdueDate = info.getOverdueDate() == null ? "": DateUtils.formatDate(info.getOverdueDate());
        sb.append(overdueDate + ReportingConstant.separator);
        String lastPaymentDate = info.getLastPaymentDate() == null ? "": DateUtils.formatDate(info.getLastPaymentDate());
        sb.append(lastPaymentDate + ReportingConstant.separator);
        String payoffDate = info.getPayoffDate() == null ? "": DateUtils.formatDate(info.getPayoffDate());
        sb.append(payoffDate + ReportingConstant.separator);
        sb.append((info.getAssureType()==null?"":info.getAssureType()) + ReportingConstant.separator);
        sb.append((info.getLoanClassify()==null?"":info.getLoanClassify()) + ReportingConstant.separator);
        sb.append((info.getNature()==null?"":info.getNature()) + ReportingConstant.separator);
        sb.append((info.getAccountStatus()==null?"":info.getAccountStatus()) + ReportingConstant.separator);
        sb.append((info.getOvdDays()==null?"0":info.getOvdDays()) + ReportingConstant.separator);
        sb.append((info.getAppstat()==null?"":info.getAppstat()) + ReportingConstant.separator);
        sb.append((info.getAmortMethod()==null?"":info.getAmortMethod()) + ReportingConstant.separator);
        sb.append((info.getRtnCardno()==null?"":info.getRtnCardno()) + ReportingConstant.separator);
        sb.append((info.getPayMode()==null?"":info.getPayMode()) + ReportingConstant.separator);
        sb.append((info.getPayCardno()==null?"":info.getPayCardno()) + ReportingConstant.separator);
        sb.append((info.getRtnDateType()==null?"":info.getRtnDateType()) + ReportingConstant.separator);
        sb.append((info.getIntrate()==null?"0.0000000000":info.getIntrate().setScale(10, BigDecimal.ROUND_HALF_UP)) + ReportingConstant.separator);
        sb.append((info.getPfltintrateOpt()==null?"":info.getPfltintrateOpt()) + ReportingConstant.separator);
        sb.append((info.getPfltintrate()==null?"":info.getPfltintrate().setScale(6, BigDecimal.ROUND_HALF_UP)) + ReportingConstant.separator);
        sb.append((info.getPintrate()==null?"0.0000000000":info.getPintrate().setScale(10, BigDecimal.ROUND_HALF_UP)) + ReportingConstant.separator);
        sb.append((info.getIscomint()==null?"":info.getIscomint()) + ReportingConstant.separator);
        sb.append((info.getPayDirect()==null?"":info.getPayDirect()) + ReportingConstant.separator);
        sb.append((info.getPaymentmode()==null?"":info.getPaymentmode()) + ReportingConstant.separator);
        sb.append((info.getCloseType()==null?"":info.getCloseType()) + ReportingConstant.separator);
        sb.append((info.getTotOvdTimes()==null?"0":info.getTotOvdTimes()) + ReportingConstant.separator);
        sb.append((info.getOvdPeri()==null?"0":info.getOvdPeri()) + ReportingConstant.separator);
        sb.append((info.getMaxOvdPeri()==null?"0":info.getMaxOvdPeri()) + ReportingConstant.separator);
        sb.append((info.getExtCnt()==null?"0":info.getExtCnt()) + ReportingConstant.separator);
        sb.append((info.getDeferCnt()==null?"0":info.getDeferCnt()) + ReportingConstant.separator);
        sb.append((info.getShortenCnt()==null?"0":info.getShortenCnt())  + ReportingConstant.separator);
        sb.append((info.getDogType()==null?"":info.getDogType())  + ReportingConstant.separator);
        sb.append((info.getDog()==null?"0":info.getDog())  + ReportingConstant.separator);
        sb.append((info.getIsdogflag()==null?"":info.getIsdogflag())  + ReportingConstant.separator);
        sb.append((info.getIndustryType()==null?"":info.getIndustryType())  + ReportingConstant.separator);
        sb.append((info.getLoanUse()==null?"":info.getLoanUse())  + ReportingConstant.separator);
        sb.append((info.getGrantMode()==null?"":info.getGrantMode())  + ReportingConstant.separator);
        sb.append((info.getCurrency()==null?"":info.getCurrency())  + ReportingConstant.separator);
        sb.append((info.getLoanAmount()==null?"0.00":info.getLoanAmount().setScale(2, BigDecimal.ROUND_HALF_UP))  + ReportingConstant.separator);
        sb.append((info.getDiscountRate()==null?"0.00":info.getDiscountRate().setScale(2, BigDecimal.ROUND_HALF_UP))  + ReportingConstant.separator);
        sb.append((info.getCurrBalance()==null?"0.00":info.getCurrBalance().setScale(2, BigDecimal.ROUND_HALF_UP))  + ReportingConstant.separator);
        sb.append((info.getPrincipalBalance()==null?"0.00":info.getPrincipalBalance().setScale(2, BigDecimal.ROUND_HALF_UP))  + ReportingConstant.separator);
        sb.append((info.getInterestBalance()==null?"0.00":info.getInterestBalance().setScale(2, BigDecimal.ROUND_HALF_UP))  + ReportingConstant.separator);
        sb.append((info.getPenaltyBalance()==null?"0.00":info.getPenaltyBalance().setScale(2, BigDecimal.ROUND_HALF_UP))  + ReportingConstant.separator);
        sb.append((info.getCompoundBalance()==null?"0.00":info.getCompoundBalance().setScale(2, BigDecimal.ROUND_HALF_UP))  + ReportingConstant.separator);
        sb.append((info.getFeeBalance()==null?"0.00":info.getFeeBalance().setScale(2, BigDecimal.ROUND_HALF_UP))  + ReportingConstant.separator);
        sb.append((info.getRemainPrincipal()==null?"0.00":info.getRemainPrincipal().setScale(2, BigDecimal.ROUND_HALF_UP))  + ReportingConstant.separator);
        sb.append((info.getAccruedInterest()==null?"0.00":info.getAccruedInterest().setScale(2, BigDecimal.ROUND_HALF_UP))  + ReportingConstant.separator);
        sb.append((info.getAccruedPenalty()==null?"0.00":info.getAccruedPenalty().setScale(2, BigDecimal.ROUND_HALF_UP))  + ReportingConstant.separator);
        sb.append((info.getAccruedCompound()==null?"0.00":info.getAccruedCompound().setScale(2, BigDecimal.ROUND_HALF_UP))  + ReportingConstant.separator);
        sb.append((info.getChargeoffFlag()==null?"":info.getChargeoffFlag()) + ReportingConstant.separator);
        sb.append((info.getChargeoffAmount()==null?"0.00":info.getChargeoffAmount().setScale(2, BigDecimal.ROUND_HALF_UP)) + ReportingConstant.separator);
        String chargeoffDate = info.getChargeoffDate() == null ? "": DateUtils.formatDate(info.getChargeoffDate());
        sb.append(chargeoffDate + ReportingConstant.separator);
        String createTime = DateUtils.format(info.getCreateTime(),"yyyy-MM-dd HH:mm:ss");
        String updateTime = DateUtils.format(info.getUpdateTime(),"yyyy-MM-dd HH:mm:ss");
        sb.append(createTime + ReportingConstant.separator);
        sb.append(updateTime);

        return sb.toString();
    }

    @Override
    public String createPaymentFileMessage(MrPaymentLog log) {
        StringBuffer sb = new StringBuffer();
        sb.append((log.getCustomerId()==null?"":log.getCustomerId()) + ReportingConstant.separator);
        sb.append((log.getLoanId()==null?"":log.getLoanId()) + ReportingConstant.separator);
        sb.append((log.getSeqNo()==null?"":log.getSeqNo()) + ReportingConstant.separator);
        sb.append((log.getOrganizationId()==null?"":log.getOrganizationId()) + ReportingConstant.separator);
        sb.append((log.getChannel()==null?"":log.getChannel()) + ReportingConstant.separator);
        sb.append((log.getProductId()==null?"":log.getProductId()) + ReportingConstant.separator);
        sb.append((log.getPaymentType()==null?"":log.getPaymentType()) + ReportingConstant.separator);
        sb.append((log.getChargeType()==null?"":log.getChargeType()) + ReportingConstant.separator);
        sb.append((log.getIsFullPay()==null?"":log.getIsFullPay()) + ReportingConstant.separator);
        sb.append((log.getPayerBank()==null?"":log.getPayerBank()) + ReportingConstant.separator);
        sb.append((log.getPayerBankName()==null?"":log.getPayerBankName()) + ReportingConstant.separator);
        sb.append((log.getPayerAccount()==null?"":log.getPayerAccount()) + ReportingConstant.separator);
        sb.append((log.getPayerAccountType()==null?"":log.getPayerAccountType()) + ReportingConstant.separator);
        sb.append((log.getAvailBalance()==null?"0.00":log.getAvailBalance().setScale(2, BigDecimal.ROUND_HALF_UP)) + ReportingConstant.separator);
        String postDate = log.getPostingDate() == null ? "":DateUtils.formatDate(log.getPostingDate());
        sb.append(postDate + ReportingConstant.separator);
        sb.append((log.getSumStatus()==null?"":log.getSumStatus()) + ReportingConstant.separator);
        sb.append((log.getCurrency()==null?"":log.getCurrency()) + ReportingConstant.separator);
        sb.append((log.getTotalAmount()==null?"0.00":log.getTotalAmount().setScale(2, BigDecimal.ROUND_HALF_UP)) + ReportingConstant.separator);
        sb.append((log.getActualcorp()==null?"0.00":log.getActualcorp().setScale(2, BigDecimal.ROUND_HALF_UP)) + ReportingConstant.separator);
        sb.append((log.getActualinte()==null?"0.00":log.getActualinte().setScale(2, BigDecimal.ROUND_HALF_UP)) + ReportingConstant.separator);
        sb.append((log.getPenalty()==null?"0.00":log.getPenalty().setScale(2, BigDecimal.ROUND_HALF_UP)) + ReportingConstant.separator);
        sb.append((log.getRepayFee()==null?"0.00":log.getRepayFee().setScale(2, BigDecimal.ROUND_HALF_UP)) + ReportingConstant.separator);
        sb.append((log.getPrepayFee()==null?"0.00":log.getPrepayFee().setScale(2, BigDecimal.ROUND_HALF_UP)) + ReportingConstant.separator);
        sb.append((log.getRepayCompoundInterest()==null?"0.00":log.getRepayCompoundInterest().setScale(2, BigDecimal.ROUND_HALF_UP)) + ReportingConstant.separator);
        sb.append((log.getBillingTenor()==null?"0":log.getBillingTenor()) + ReportingConstant.separator);
        sb.append((log.getTotalTenor()==null?"0":log.getTotalTenor()) + ReportingConstant.separator);
        sb.append((log.getPartnerId()==null?"":log.getPartnerId()) + ReportingConstant.separator);
        sb.append((log.getRevealMobel()==null?"":log.getRevealMobel()) + ReportingConstant.separator);
        sb.append((log.getTotalDays()==null?"0":log.getTotalDays()) + ReportingConstant.separator);
        sb.append((log.getCompensatoryFlag()==null?"":log.getCompensatoryFlag()) + ReportingConstant.separator);
        sb.append((log.getNonAccrualsFlag()==null?"":log.getNonAccrualsFlag()) + ReportingConstant.separator);
        String createTime = DateUtils.format(log.getCreateTime(),"yyyy-MM-dd HH:mm:ss");
        String updateTime = DateUtils.format(log.getUpdateTime(),"yyyy-MM-dd HH:mm:ss");
        sb.append(createTime + ReportingConstant.separator);
        sb.append(updateTime);
        return sb.toString();
    }

    @Override
    public String createPlanFileMessage(MrRepaymentPlan info) {
        StringBuffer sb = new StringBuffer();
        sb.append((info.getChannel()==null?"":info.getChannel()) + ReportingConstant.separator);
        sb.append((info.getProductId()==null?"":info.getProductId()) + ReportingConstant.separator);
        sb.append((info.getOrganizationId()==null?"":info.getOrganizationId()) + ReportingConstant.separator);
        sb.append((info.getCustomerId()==null?"":info.getCustomerId()) + ReportingConstant.separator);
        sb.append((info.getPlanStatus()==null?"":info.getPlanStatus()) + ReportingConstant.separator);
        sb.append((info.getLoanId()==null?"":info.getLoanId()) + ReportingConstant.separator);
        sb.append((info.getBillingTenor()==null?"0":info.getBillingTenor()) + ReportingConstant.separator);
        String payDate = info.getPaydate() == null ? "" : DateUtils.formatDate(info.getPaydate());
        sb.append(payDate + ReportingConstant.separator);
        String actualpaydate = info.getActualpaydate() == null ? "" : DateUtils.formatDate(info.getActualpaydate());
        sb.append(actualpaydate + ReportingConstant.separator);
        String periodpaydate = info.getPeriodpaydate() == null ? "" : DateUtils.formatDate(info.getPeriodpaydate());
        sb.append(periodpaydate + ReportingConstant.separator);
        sb.append((info.getTotalAmount()==null?"0.00":info.getTotalAmount().setScale(2, BigDecimal.ROUND_HALF_UP)) + ReportingConstant.separator);
        sb.append((info.getPrincipalAmount()==null?"0.00":info.getPrincipalAmount().setScale(2, BigDecimal.ROUND_HALF_UP)) + ReportingConstant.separator);
        sb.append((info.getInterestAmount()==null?"0.00":info.getInterestAmount().setScale(2, BigDecimal.ROUND_HALF_UP)) + ReportingConstant.separator);
        sb.append((info.getPenaltyInterest()==null?"0.00":info.getPenaltyInterest().setScale(2, BigDecimal.ROUND_HALF_UP))  + ReportingConstant.separator);
        sb.append((info.getCompoundInterest()==null?"0.00":info.getCompoundInterest().setScale(2, BigDecimal.ROUND_HALF_UP)) + ReportingConstant.separator);
        sb.append((info.getFeeAmount()==null?"0.00":info.getFeeAmount().setScale(2, BigDecimal.ROUND_HALF_UP)) + ReportingConstant.separator);
        sb.append((info.getRepayPrincipal()==null?"0.00":info.getRepayPrincipal().setScale(2, BigDecimal.ROUND_HALF_UP))  + ReportingConstant.separator);
        sb.append((info.getRepayInterest()==null?"0.00":info.getRepayInterest().setScale(2, BigDecimal.ROUND_HALF_UP)) + ReportingConstant.separator);
        sb.append((info.getRepayPenaltyInterest()==null?"0.00":info.getRepayPenaltyInterest().setScale(2, BigDecimal.ROUND_HALF_UP)) + ReportingConstant.separator);
        sb.append((info.getRepayCompoundInterest()==null?"0.00":info.getRepayCompoundInterest().setScale(2, BigDecimal.ROUND_HALF_UP)) + ReportingConstant.separator);
        sb.append((info.getRepayFee()==null?"0.00":info.getRepayFee().setScale(2, BigDecimal.ROUND_HALF_UP)) + ReportingConstant.separator);
        sb.append((info.getPayOffStatus()==null?"":info.getPayOffStatus()) + ReportingConstant.separator);
        String payoffDate = info.getPayoffDate()== null ? "" : DateUtils.formatDate(info.getPayoffDate());
        sb.append(payoffDate + ReportingConstant.separator);
        sb.append((info.getWaivedAmount()==null?"0.00":info.getWaivedAmount().setScale(2, BigDecimal.ROUND_HALF_UP)) + ReportingConstant.separator);
        sb.append((info.getBalTransFlag()==null?"":info.getBalTransFlag()) + ReportingConstant.separator);
        sb.append((info.getDelqDays()==null?"0":info.getDelqDays()) + ReportingConstant.separator);
        sb.append((info.getOverDueAmount()==null?"0.00":info.getOverDueAmount().setScale(2, BigDecimal.ROUND_HALF_UP)) + ReportingConstant.separator);
        sb.append((info.getCompensateFlag()==null?"":info.getCompensateFlag()) + ReportingConstant.separator);
        String createTime = DateUtils.format(info.getCreateTime(),"yyyy-MM-dd HH:mm:ss");
        String updateTime = DateUtils.format(info.getUpdateTime(),"yyyy-MM-dd HH:mm:ss");
        sb.append(createTime + ReportingConstant.separator);
        sb.append(updateTime);
        return sb.toString();
    }

    @Override
    public String createLimitFileMessage(CmLimitAdjustLog log) throws TxnException {
        StringBuffer sb = new StringBuffer();
        sb.append((log.getOrganizationId()==null?"":log.getOrganizationId()) + ReportingConstant.separator);
        sb.append((log.getCustomerId()==null?"":log.getCustomerId()) + ReportingConstant.separator);
        sb.append((log.getLimitId()==null?"":log.getLimitId()) + ReportingConstant.separator);
        CreditLimitTypeRes res = creditLimitTypeService.findByLimitIdAndOrgIdAndTenId(log.getLimitId(),log.getOrganizationId(),log.getTenantId());
        sb.append(StringUtils.filterSpecialChar(res.getLimitDesc()) + ReportingConstant.separator);
        sb.append((res.getLimitClass()==null?"":res.getLimitClass()) + ReportingConstant.separator);
        sb.append((res.getUseMode()==null?"":res.getUseMode()) + ReportingConstant.separator);
        sb.append((res.getUnderControl()==null?"":res.getUnderControl()) + ReportingConstant.separator);
        sb.append((log.getTemplateId()==null?"":log.getTemplateId()) + ReportingConstant.separator);
        PrCreditLimitTemplate template = extPrCreditLimitTemplateMapper.selectLimitTemplateByTempIdAndTenId(log.getTemplateId(), log.getTenantId());
        sb.append((template.getTemplateDesc()==null?"":template.getTemplateDesc()) + ReportingConstant.separator);
        sb.append((log.getChannel()==null?"":log.getChannel()) + ReportingConstant.separator);
        sb.append((log.getDataSource()==null?"":log.getDataSource()) + ReportingConstant.separator);
        sb.append((log.getAdjustType()==null?"":log.getAdjustType()) + ReportingConstant.separator);
        sb.append(StringUtils.filterSpecialChar(log.getAdjustReason()) + ReportingConstant.separator);
        sb.append((log.getLimitPermBefore()==null?"0.00":log.getLimitPermBefore().setScale(2, BigDecimal.ROUND_HALF_UP)) + ReportingConstant.separator);
        sb.append((log.getLimitPermAfter()==null?"0.00":log.getLimitPermAfter().setScale(2, BigDecimal.ROUND_HALF_UP)) + ReportingConstant.separator);
        sb.append((log.getLimitTempBefore()==null?"0.00":log.getLimitTempBefore().setScale(2, BigDecimal.ROUND_HALF_UP)) + ReportingConstant.separator);
        sb.append((log.getLimitTempAfter()==null?"0.00":log.getLimitTempAfter().setScale(2, BigDecimal.ROUND_HALF_UP)) + ReportingConstant.separator);
        String tempStartDate = log.getLimitTempStartDateBefore()== null ? "" : DateUtils.formatDate(log.getLimitTempStartDateBefore());
        sb.append(tempStartDate + ReportingConstant.separator);
        String tempEndDate = log.getLimitTempEndDateBefore()== null ? "" : DateUtils.formatDate(log.getLimitTempEndDateBefore());
        sb.append(tempEndDate + ReportingConstant.separator);
        String tempStartAfter = log.getLimitTempStartDateAfter()== null ? "" : DateUtils.formatDate(log.getLimitTempStartDateAfter());
        sb.append(tempStartAfter + ReportingConstant.separator);
        String tempEndAfter = log.getLimitTempEndDateAfter()== null ? "" : DateUtils.formatDate(log.getLimitTempEndDateAfter());
        sb.append(tempEndAfter + ReportingConstant.separator);
        String updateTime = DateUtils.formatDate(log.getUpdateTime(),DateUtils.DATETIME_PATTERN);
        sb.append(updateTime);

        return sb.toString();
    }


    @Override
    public String createStagingFileMessage(TlLoanStagingMapping tl) {
        StringBuffer sb = new StringBuffer();
        sb.append((tl.getOrganizationId()==null?"":tl.getOrganizationId()) + ReportingConstant.separator);
        sb.append((tl.getChannel()==null?"":tl.getChannel()) + ReportingConstant.separator);
        sb.append((tl.getCustomerId()==null?"":tl.getCustomerId()) + ReportingConstant.separator);
        sb.append((tl.getStagingLoanId()==null?"":tl.getStagingLoanId()) + ReportingConstant.separator);
        sb.append((tl.getLoanAmount()==null?"0.00":tl.getLoanAmount().setScale(2, BigDecimal.ROUND_HALF_UP)) + ReportingConstant.separator);
        String busiDate = DateUtils.format(tl.getBusinessDate());
        sb.append(busiDate + ReportingConstant.separator);
        sb.append((tl.getTotalTenor()==null?"":tl.getTotalTenor()) + ReportingConstant.separator);
        sb.append((tl.getOriginalLoanId()==null?"":tl.getOriginalLoanId()) + ReportingConstant.separator);
        sb.append((tl.getOriginalLoanAomount()==null?"0.00":tl.getOriginalLoanAomount().setScale(2, BigDecimal.ROUND_HALF_UP)) + ReportingConstant.separator);
        sb.append((tl.getStagingAmount()==null?"0.00":tl.getStagingAmount().setScale(2, BigDecimal.ROUND_HALF_UP)) + ReportingConstant.separator);
        sb.append((tl.getStagingPrincipalAmount()==null?"0.00":tl.getStagingPrincipalAmount().setScale(2, BigDecimal.ROUND_HALF_UP)) + ReportingConstant.separator);
        sb.append((tl.getStagingInterestAmount()==null?"0.00":tl.getStagingInterestAmount().setScale(2, BigDecimal.ROUND_HALF_UP)) + ReportingConstant.separator);
        sb.append((tl.getStagingFeeAmount()==null?"0.00":tl.getStagingFeeAmount().setScale(2, BigDecimal.ROUND_HALF_UP)) + ReportingConstant.separator);
        sb.append((tl.getStagingPenaltyAmount()==null?"0.00":tl.getStagingPenaltyAmount().setScale(2, BigDecimal.ROUND_HALF_UP)) + ReportingConstant.separator);
        sb.append((tl.getStagingCompoundAmount()==null?"0.00":tl.getStagingCompoundAmount().setScale(2, BigDecimal.ROUND_HALF_UP)) + ReportingConstant.separator);
        sb.append(tl.getSumStatus()==null?"":tl.getSumStatus());
        return sb.toString();
    }

    @Override
    public void generatingFile(List<String> messageList, String reportingPath, String fileName, String fileType)  {
        PrOrganizationTable org = organizationTableService.findByOrgIdForBatch(ReportingConstant.DEFAULT_ORG_NUMBER);
        String toDay = DateUtils.format(org.getToday(),"yyyyMMdd");

        String collectionFileName = fileType+ "_" + toDay + "_" + fileName + ".txt";

        String filePath = reportingPath + org.getTenantId() + File.separator + toDay + File.separator;

        Path reportingFile = Paths.get(filePath + collectionFileName);

        Integer i = 0;
        try(FileWriter bfw = new FileWriter(reportingFile.toFile(),true);
            BufferedWriter writer = new BufferedWriter(bfw,10240)) {
            if(reportingFile.toFile().length() != 0){
                writer.write("\r\n");
            }
            for (String message : messageList) {
                i++;
                if(i == messageList.size()){
                    writer.write(message);
                }else{
                    writer.write(message + "\r\n");
                }
            }
            writer.flush();
        } catch (IOException e) {
            logger.error("报送文件生成异常，异常信息：",e);
            throw new RuntimeException(e);
        }
    }

    @Override
    public void mergeReportingFile(String reportingPath,String toDay,String fileType)  {
        //获取目录下所有文件
        File file = new File(reportingPath);
        File[] tempList = file.listFiles();
        if(tempList == null || tempList.length == 0){
            logger.error("文件合并，未获取到需要合并的文件");
            throw new RuntimeException("文件合并，未获取到需要合并的文件");
        }

        List<File> mergeList = new ArrayList<>();

        for(int i = 0; i < tempList.length; i++){
            String fileName = tempList[i].getName();
            if(fileType.length()>fileName.length()){
                continue;
            }
            String subStr = fileName.substring(0,fileType.length());
            if(fileType.equals(subStr)){
                mergeList.add(tempList[i]);
            }
        }
        //合并文件
        File resultFile = new File(reportingPath + fileType + "_" + toDay + ".txt");


        Boolean isNullFile = true;
        try(FileChannel resultFileChannel= new FileOutputStream(resultFile, true).getChannel()){
            for(int i = 0; i < mergeList.size(); i++){
                FileChannel blk1 = new FileInputStream(mergeList.get(i)).getChannel();
                if(i == 0 && blk1.size() == 0){
                    resultFile.createNewFile();
                }else if (blk1.size() != 0){
                    if(!isNullFile && i != 0){
                        //换行
                        ByteBuffer buf = ByteBuffer.allocate(48);
                        buf.clear();
                        buf.put("\r\n".getBytes());
                        buf.flip();
                        while(buf.hasRemaining()) {
                            resultFileChannel.write(buf);
                        }
                    }
                    //写入新文件
                    resultFileChannel.transferFrom(blk1, resultFileChannel.size(), blk1.size());
                    isNullFile = false;
                }
                blk1.close();
            }
        } catch (IOException e) {
            logger.error("报送文件合并异常，异常信息：",e);
            throw new RuntimeException(e);
        }


        // 获取文件总条数
        Long count = null;
        try {
            count = Files.lines(Paths.get(reportingPath + fileType + "_" + toDay + ".txt")).count();
        } catch (IOException e) {
            logger.error("读取文件条数异常：",e);
            throw new RuntimeException(e);
        }
        // 生成OK文件
        File okFile = new File(reportingPath + fileType + "_" + toDay + ".ok");
        try (FileWriter fw = new FileWriter(okFile);
             BufferedWriter writer = new BufferedWriter(fw) ){
            writer.write(count+"");
            writer.flush();
        } catch (IOException e) {
            logger.error("生成OK文件失败");
            throw new RuntimeException(e);
        }
    }
}
